﻿using System.Linq;
using System.Threading.Tasks;
using System.Collections.ObjectModel;
using System.Threading;

namespace OmniKits.Async
{
    using Core;

    public abstract class TaskDispatcher<T> : SimpleRunTaskBase<Task>
        where T : IRunTask<Task>
    {
        public ObservableCollection<T> QueuedTasks { get; } = new ObservableCollection<T>();

        protected abstract bool IsReadyToRun(T task);

        protected override async Task StartTask(CancellationToken cancellationToken)
        {
            for (; ;)
            {
                var hasTask = QueuedTasks.Where(t => t.IsTaskRunning()).FirstOrDefault();
                if (hasTask != null)
                {
                    cancellationToken.ThrowIfCancellationRequested();
                    await hasTask.CurrentTask;
                    continue;
                }

                var pending = QueuedTasks.Where(IsReadyToRun).FirstOrDefault();
                if (pending != null)
                {
                    //cancellationToken.ThrowIfCancellationRequested();
                    await pending.Run(cancellationToken);
                    continue;
                }

                break;
            }
        }
    }
}
